package com.kpx.app.http;

import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.kpx.app.Application;
import com.kpx.app.base.ActivityDelegate;
import com.kpx.app.configs.Constants;
import com.kpx.app.fragment.FragmentDelegate;
import com.kpx.app.utils.MyHashMap;
import com.kpx.app.utils.datautils.FileUtils;
import com.kpx.app.utils.dbutils.SpUtil;
import com.kpx.app.utils.systemutils.SystemConfigUtils;
import com.kpx.app.utils.systemutils.SystemUtil;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * 数据请求类
 *
 * @author scott
 */
public class HttpDataLoader extends HttpDataApi implements ActivityDelegate, FragmentDelegate {
    private static RequestQueue mRequestQueue;
    private Class classname;
    private Integer parseType;
    private OnRequestCallback onRequestCallback;
    // 当前正在处理的Request
    private ArrayList<Request> mCurrentRequests;

    public HttpDataLoader(OnRequestCallback requestCallback, Class classname, Integer parseType) {
        this.classname = classname;
        this.parseType = parseType;
        onRequestCallback = requestCallback;
        if (mRequestQueue == null) {
            if (Application.isHttps) {
//                mRequestQueue = MyVolley.newRequestQueue(Application.instance, null, true, R.raw.lience);//需要配置证书才能使用
            } else {
                mRequestQueue = Volley.newRequestQueue(Application.instance);
            }
        }
        mCurrentRequests = new ArrayList<>();
    }

    /**
     * 发起GET请求
     *
     * @param shortUrl 短链接
     * @param needAuth 是否需要认证,即携带Token参数
     * @param params GET请求参数,需要按顺序传入 (Restful风格API)
     */
    @Override
    public void GET(@NonNull final String shortUrl, boolean needAuth, String... params) {
        HttpDataRequest request = new HttpDataRequest(Request.Method.GET, shortUrl, onRequestCallback,classname,parseType);
        request.setGetParams(params);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (needAuth) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    private boolean checkNet(@NonNull String shortUrl) {
        if (!SystemUtil.isNetworkAvaliable()) {
            if (onRequestCallback != null) {
                ResObj disconnectedError = JSON.parseObject(generateDisconnectedError(), ResObj.class);
                onRequestCallback.onRequestSuccess(shortUrl, disconnectedError, false);
            }
            return true;
        }
        return false;
    }

    public String generateDisconnectedError() {
        return generateError(-2, "未连接网络");
    }
    public String generateError(int errorCode, String errorMsg) {
        ResObj networkResult = new ResObj();
        networkResult.setCode(errorCode);
        networkResult.setData(errorMsg);
        networkResult.setMsg(errorMsg);
        return JSON.toJSONString(networkResult);
    }
    /**
     * 发起GET请求
     * 使用?形式拼接GET请求参数请使用该方法
     *
     * @param shortUrl 短链接
     */
    public void GET(@NonNull final String shortUrl, @NonNull ReqObj reqObj) {
        HttpDataRequest request = new HttpDataRequest(Request.Method.GET, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        request.setGetReqObj(reqObj);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (reqObj.needAuth()) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    /**
     * 发起GET请求
     *
     * @param rootUrl 根域名
     * @param shortUrl 短链接
     * @param needAuth 是否需要认证,即携带Token参数
     * @param params GET请求参数,需要按顺序传入 (Restful风格API)
     */
    public void GET(@NonNull final String rootUrl, @NonNull final String shortUrl, boolean needAuth, String... params) {
        HttpDataRequest request = new HttpDataRequest(Request.Method.GET, rootUrl, shortUrl, onRequestCallback,classname,parseType);
        request.setGetParams(params);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (needAuth) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    /**
     * 发起GET请求
     * 使用?形式拼接GET请求参数请使用该方法
     *
     * @param shortUrl 短链接
     */
    public void GET(@NonNull String rootUrl, @NonNull final String shortUrl, @NonNull ReqObj reqObj) {
        HttpDataRequest request = new HttpDataRequest(Request.Method.GET, rootUrl, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        request.setGetReqObj(reqObj);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (reqObj.needAuth()) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    /**
     * 发起POST请求
     *
     * @param shortUrl 短链接
     * @param reqObj POST请求参数
     */
    @Override
    public void POST(@NonNull final String shortUrl, @NonNull ReqObj reqObj) {
        final HttpDataRequest request = new HttpDataRequest(Request.Method.POST, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (reqObj.needAuth()) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        request.setNeedEncrypt(reqObj.needExcrypt());
        if (!TextUtils.isEmpty(reqObj.getContentType())) {
            request.setBodyContentType(reqObj.getContentType());
            request.setBody(JSONObject.toJSONString(reqObj));
        } else {
            String jsonString = JSON.toJSONString(reqObj);
            request.setPostParams(JSON.parseObject(jsonString, HashMap.class));
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    /**
     * 发起POST请求
     *
     * @param shortUrl 短链接
     * @param reqObj POST请求参数
     */
    public void POST(@NonNull String rootUrl, @NonNull final String shortUrl, @NonNull ReqObj reqObj) {
        final HttpDataRequest request = new HttpDataRequest(Request.Method.POST, rootUrl, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (reqObj.needAuth()) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        if (!TextUtils.isEmpty(reqObj.getContentType())) {
            request.setBodyContentType(reqObj.getContentType());
            request.setBody(JSONObject.toJSONString(reqObj));
        } else {
            String jsonString = JSON.toJSONString(reqObj);
            request.setPostParams(JSON.parseObject(jsonString, HashMap.class));
        }
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    /**
     * 发起POST请求
     *
     * @param shortUrl 短链接
     * @param map POST请求参数
     */
    public void POST(@NonNull String rootUrl, @NonNull final String shortUrl, boolean needAuth, MyHashMap map) {
        final HttpDataRequest request = new HttpDataRequest(Request.Method.POST, rootUrl, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (needAuth) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        try {
            String jsonString = map.toJSONString();
            request.setPostParams(JSON.parseObject(jsonString, HashMap.class));
        }catch (Exception e){
            request.setPostParams(map);
        }
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    private void addDeviceInfo(HttpDataRequest request) {
        // 传入平台版本等相关数据
        // 平台
        request.addHeaders("platform", "Android");
        // 版本名称
        request.addHeaders("versionName", SystemConfigUtils.getVersionName() + "");
        // 版本号
        request.addHeaders("versionCode", SystemConfigUtils.getVersionCode() + "");
        // 系统版本
        request.addHeaders("sdkVersion", Build.VERSION.SDK_INT + "");
        request.addHeaders("deviceName", Build.MANUFACTURER+Build.MODEL);
    }

    /**
     * 发起POST请求(使用MyHashMap)
     * cc
     *
     * @param shortUrl 短链接
     * @param map POST请求参数
     */
    public void POST(@NonNull final String shortUrl, boolean needAuth, @NonNull MyHashMap map) {
        final HttpDataRequest request = new HttpDataRequest(Request.Method.POST, shortUrl, onRequestCallback,classname,parseType);
        request.setShouldCache(true);
        // 设置请求重试策略
        int timeoutMs = 10000;
        if (Constants.DEBUG) {
            timeoutMs = 10000;
        }
        request.setRetryPolicy(new DefaultRetryPolicy(timeoutMs, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // 如果需要携带Token信息,needAuth需要设置为true
        if (needAuth) {
            String userToken = SpUtil.getString(Constants.KEY_USER_TOKEN);
            if (!TextUtils.isEmpty(userToken)) {
                request.addHeaders(Constants.KEY_USER_TOKEN, userToken);
            }
        }
        String jsonString = map.toJSONString();
        request.setPostParams(JSON.parseObject(jsonString, HashMap.class));
        // 传入平台版本等相关数据
        // 平台
        addDeviceInfo(request);
        if (checkNet(shortUrl)) return;
        mRequestQueue.add(request);
        mCurrentRequests.add(request);
    }

    // 结束调用后调用该方法移除事件监听,并标记为cancel
    public void finish() {
        onRequestCallback = null;
        if (null != mCurrentRequests) {
            for (Request request : mCurrentRequests) {
                request.cancel();
            }
            mCurrentRequests.clear();
            mCurrentRequests = null;
        }
    }

    @Override
    public void onAttach(Context context) {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

    }

    @Override
    public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    }

    @Override
    public void onActivityCreate(Bundle savedInstanceState) {

    }

    @Override
    public void onStart() {

    }

    @Override
    public void onResume() {

    }

    @Override
    public void onPause() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void onDestroyView() {
        finish();
    }

    @Override
    public void onFragmentDestroy() {
        finish();
    }

    @Override
    public void onDetach() {

    }

    @Override
    public void onActivityDestroy() {
        finish();
    }

}
